package com.english.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.english.entity.Lesson;
import com.english.entity.LessonLog;
import com.english.entity.RechargeProcessLog;
import com.english.entity.StudentRecharge;
import com.english.entity.User;
import com.english.mapper.LessonLogMapper;
import com.english.mapper.LessonMapper;
import com.english.mapper.RechargeProcessLogMapper;
import com.english.mapper.StudentRechargeMapper;
import com.english.mapper.UserMapper;
import com.english.service.LessonService;
import com.english.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.english.mapper.CourseClassMapper;
import com.english.service.StudentClassHoursService;
import java.util.Map;
import java.util.stream.Collectors;
import com.english.entity.CourseClass;

/**
 * 课时管理服务实现类
 *
 * @author wlq
 * @since 2025-08-04
 */
@Service
@Transactional
public class LessonServiceImpl implements LessonService {

    @Autowired
    private LessonMapper lessonMapper;

    @Autowired
    private LessonLogMapper lessonLogMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private StudentRechargeMapper studentRechargeMapper;

    @Autowired
    private RechargeProcessLogMapper rechargeProcessLogMapper;

    @Autowired
    private CourseClassMapper courseClassMapper;

    @Autowired
    private StudentClassHoursService studentClassHoursService;

    @Override
    public Lesson getLessonByStudentId(Long studentId) {
        return lessonMapper.selectByStudentId(studentId);
    }

    @Override
    public List<LessonLog> getLessonLogsByStudentId(Long studentId) {
        return lessonLogMapper.selectByStudentId(studentId);
    }

    @Override
    public boolean adjustLesson(LessonAdjustVO adjustVO, Long adminId) {
        // 1. 查询课时主表
        Lesson lesson = null;
        
        // 如果指定了班级ID，查询特定班级的课时
        if (adjustVO.getClassId() != null) {
            lesson = lessonMapper.selectByStudentIdAndClassId(adjustVO.getStudentId(), adjustVO.getClassId());
        } else {
            // 兼容性：如果没有指定班级ID，查询第一个班级
            lesson = lessonMapper.selectByStudentId(adjustVO.getStudentId());
        }
        
        if (lesson == null) {
            // 初始化新记录
            lesson = new Lesson();
            lesson.setStudentId(adjustVO.getStudentId());
            lesson.setClassId(adjustVO.getClassId() != null ? adjustVO.getClassId() : 1L); // 默认班级ID=1
            lesson.setTotalHours(Math.max(adjustVO.getChangeValue(), 0));
            lesson.setUsedHours(0);
            lesson.setRemainingHours(Math.max(adjustVO.getChangeValue(), 0));
            lessonMapper.insert(lesson);
        } else {
            // 更新现有记录
            lesson.setTotalHours(lesson.getTotalHours() + Math.max(adjustVO.getChangeValue(), 0));
            lesson.setRemainingHours(lesson.getRemainingHours() + adjustVO.getChangeValue());
            // usedHours不变
            lessonMapper.updateById(lesson);
        }

        // 2. 写入日志
        LessonLog log = new LessonLog();
        log.setStudentId(adjustVO.getStudentId());
        log.setChangeValue(adjustVO.getChangeValue());
        log.setType(LessonLog.ChangeType.ADJUSTMENT);
        log.setTitle(adjustVO.getTitle());
        // 保证title不为null
        if (log.getTitle() == null) {
            log.setTitle("");
        }
        log.setDescription(adjustVO.getDescription());
        log.setTime(new Date());
        log.setAdminId(adminId);
        lessonLogMapper.insert(log);

        return true;
    }

    @Override
    public boolean useLesson(Long studentId, Integer hours, String title, String description, Long adminId) {
        // 1. 查询课时主表
        Lesson lesson = lessonMapper.selectByStudentId(studentId);
        if (lesson == null) {
            throw new RuntimeException("该学生没有课时记录");
        }

        if (lesson.getRemainingHours() < hours) {
            throw new RuntimeException("剩余课时不足");
        }

        // 2. 更新课时
        lesson.setUsedHours(lesson.getUsedHours() + hours);
        lesson.setRemainingHours(lesson.getRemainingHours() - hours);
        lessonMapper.updateById(lesson);

        // 3. 写入日志
        LessonLog log = new LessonLog();
        log.setStudentId(studentId);
        log.setChangeValue(-hours); // 负数表示减少
        log.setType(LessonLog.ChangeType.CLASS);
        log.setTitle(title);
        log.setDescription(description);
        log.setTime(new Date());
        log.setAdminId(adminId);
        lessonLogMapper.insert(log);

        return true;
    }

    @Override
    public LessonStatsVO getAdminStats() {
        LessonStatsVO stats = new LessonStatsVO();

        // 总学生数（只统计学生角色）
        Integer totalStudents = userMapper.countStudents();
        stats.setTotalStudents(totalStudents != null ? totalStudents : 0);

        // 总课时数
        Integer totalHours = lessonMapper.sumTotalHours();
        stats.setTotalHours(totalHours != null ? totalHours : 0);

        return stats;
    }

    @Override
    public List<StudentListVO> getStudentList(String keyword, String filter) {
        List<StudentListVO> students = new ArrayList<>();

        // 获取所有学生（role=0）
        List<User> userList = userMapper.selectStudents(keyword);

        for (User user : userList) {
            StudentListVO student = new StudentListVO();
            student.setId(user.getId());
            student.setStudentName(user.getName());
            student.setParentPhone(user.getPhone());

            // 获取课时信息
            Lesson lesson = lessonMapper.selectByStudentId(user.getId());
            if (lesson != null) {
                student.setTotalHours(lesson.getTotalHours());
                student.setUsedHours(lesson.getUsedHours());
                student.setRemainingHours(lesson.getRemainingHours());
            } else {
                student.setTotalHours(0);
                student.setUsedHours(0);
                student.setRemainingHours(0);
            }

            // 根据filter过滤
            boolean shouldInclude = true;
            if ("insufficient".equals(filter) && lesson != null && lesson.getRemainingHours() >= 5) {
                shouldInclude = false;
            } else if ("usedup".equals(filter) && lesson != null && lesson.getRemainingHours() > 0) {
                shouldInclude = false;
            }

            if (shouldInclude) {
                students.add(student);
            }
        }

        return students;
    }

    @Override
    public boolean batchAdjust(BatchOperationVO operationVO, Long adminId) {
        for (Long studentId : operationVO.getStudentIds()) {
            LessonAdjustVO adjustVO = new LessonAdjustVO();
            adjustVO.setStudentId(studentId);
            adjustVO.setChangeValue(operationVO.getHours());
            adjustVO.setTitle("批量调整");
            adjustVO.setDescription(operationVO.getDescription());
            adjustLesson(adjustVO, adminId);
        }
        return true;
    }

    @Override
    public List<StudentRecharge> getStudentRechargeList() {
        LambdaQueryWrapper<StudentRecharge> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StudentRecharge::getIsProcessed, 0) // 未处理
                   .eq(StudentRecharge::getPaymentStatus, 1); // 支付成功
        List<StudentRecharge> list = studentRechargeMapper.selectList(queryWrapper);
        return list;
    }

    @Override
    public void handleStudentRecharge(Long userId, Long adminId, Integer hoursAdded, Integer classId, String processNotes) {
        // 1. 获取该学生所有未处理的已支付充值记录
        LambdaQueryWrapper<StudentRecharge> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StudentRecharge::getUserId, userId)
                   .eq(StudentRecharge::getPaymentStatus, 1) // 只处理已支付的
                   .eq(StudentRecharge::getIsProcessed, 0); // 且未处理的
        List<StudentRecharge> unprocessedRecharges = studentRechargeMapper.selectList(queryWrapper);
        
        // 2. 计算本次处理的总金额
        BigDecimal totalProcessedAmount = unprocessedRecharges.stream()
                .map(StudentRecharge::getAmount)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        
        // 3. 更新充值记录状态为已处理
        StudentRecharge studentRecharge = new StudentRecharge();
        studentRecharge.setIsProcessed(1);
        studentRechargeMapper.update(studentRecharge, queryWrapper);

        // 4. 创建处理日志，记录本次处理的总金额
        if (!unprocessedRecharges.isEmpty()) {
            // 使用第一条充值记录的ID作为关联
            RechargeProcessLog processLog = new RechargeProcessLog();
            processLog.setRechargeId(unprocessedRecharges.get(0).getId().intValue());
            processLog.setAdminId(adminId);
            processLog.setProcessTime(LocalDateTime.now());
            processLog.setHoursAdded(hoursAdded);
            processLog.setClassId(classId);
            processLog.setProcessedAmount(totalProcessedAmount);
            processLog.setProcessNotes(processNotes);
            rechargeProcessLogMapper.insert(processLog);
        }
    }

    @Override
    public List<RechargeProcessLogVO> getRechargeProcessLogs() {
        return rechargeProcessLogMapper.getRechargeProcessLogs();
    }

    @Override
    public boolean batchRecharge(BatchRechargeVO batchRechargeVO, Long adminId) {
        // 验证参数
        if (batchRechargeVO == null || batchRechargeVO.getStudentIds() == null || batchRechargeVO.getStudentIds().isEmpty()) {
            throw new RuntimeException("学生ID列表不能为空");
        }

        if (batchRechargeVO.getHours() <= 0) {
            throw new RuntimeException("充值课时数必须大于0");
        }

        Date now = new Date();
        String title = "批量充值";
        String description = batchRechargeVO.getDescription() != null ? batchRechargeVO.getDescription() : "批量充值" + batchRechargeVO.getHours() + "课时";

        // 遍历学生ID列表，为每个学生充值课时
        for (Long studentId : batchRechargeVO.getStudentIds()) {
            // 检查学生是否存在
            User user = userMapper.selectById(studentId);
            if (user == null || user.getRole() != 0) {
                throw new RuntimeException("学生ID: " + studentId + " 不存在或不是学生角色");
            }

            // 查询课时主表
            Lesson lesson = lessonMapper.selectByStudentId(studentId);
            if (lesson == null) {
                // 初始化
                lesson = new Lesson();
                lesson.setStudentId(studentId);
                lesson.setTotalHours(batchRechargeVO.getHours());
                lesson.setUsedHours(0);
                lesson.setRemainingHours(batchRechargeVO.getHours());
                lessonMapper.insert(lesson);
            } else {
                // 更新课时
                lesson.setTotalHours(lesson.getTotalHours() + batchRechargeVO.getHours());
                lesson.setRemainingHours(lesson.getRemainingHours() + batchRechargeVO.getHours());
                lessonMapper.updateById(lesson);
            }

            // 写入课时变动日志
            LessonLog log = new LessonLog();
            log.setStudentId(studentId);
            log.setChangeValue(batchRechargeVO.getHours());
            log.setType(LessonLog.ChangeType.RECHARGE);
            log.setTitle(title);
            log.setDescription(description);
            log.setTime(now);
            // 管理员ID可以设置为当前登录管理员，这里假设通过某种方式获取
            // 如果无法获取管理员ID，可以设置为null或0
            log.setAdminId(adminId); // 实际应用中需要修改此处
            lessonLogMapper.insert(log);
        }

        return true;
    }

    @Override
    public void handleStudentRechargeMultiClass(Long userId, Long adminId, Map<Long, Integer> classHoursMap, String processNotes) {
        // 1. 获取该学生所有未处理的已支付充值记录
        LambdaQueryWrapper<StudentRecharge> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StudentRecharge::getUserId, userId)
                   .eq(StudentRecharge::getPaymentStatus, 1) // 只处理已支付的
                   .eq(StudentRecharge::getIsProcessed, 0); // 且未处理的
        List<StudentRecharge> unprocessedRecharges = studentRechargeMapper.selectList(queryWrapper);
        
        // 2. 计算本次处理的总金额
        BigDecimal totalProcessedAmount = unprocessedRecharges.stream()
                .map(StudentRecharge::getAmount)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        
        // 3. 计算总课时数
        int totalHours = classHoursMap.values().stream().mapToInt(Integer::intValue).sum();
        
        // 4. 为每个班级分配课时到lesson表
        for (Map.Entry<Long, Integer> entry : classHoursMap.entrySet()) {
            Long classId = entry.getKey();
            Integer hours = entry.getValue();
            
            if (hours > 0) {
                // 查询该学生在该班级的课时记录
                Lesson lesson = lessonMapper.selectByStudentIdAndClassId(userId, classId);
                
                if (lesson == null) {
                    // 创建新记录
                    lesson = new Lesson();
                    lesson.setStudentId(userId);
                    lesson.setClassId(classId);
                    lesson.setTotalHours(hours);
                    lesson.setUsedHours(0);
                    lesson.setRemainingHours(hours);
                    lessonMapper.insert(lesson);
                } else {
                    // 更新现有记录
                    lesson.setTotalHours(lesson.getTotalHours() + hours);
                    lesson.setRemainingHours(lesson.getRemainingHours() + hours);
                    lessonMapper.updateById(lesson);
                }
            }
        }
        
        // 5. 更新充值记录状态为已处理
        StudentRecharge studentRecharge = new StudentRecharge();
        studentRecharge.setIsProcessed(1);
        studentRechargeMapper.update(studentRecharge, queryWrapper);

        // 6. 为每个班级创建单独的处理日志
        if (!unprocessedRecharges.isEmpty()) {
            for (Map.Entry<Long, Integer> entry : classHoursMap.entrySet()) {
                Long classId = entry.getKey();
                Integer hours = entry.getValue();
                
                if (hours > 0) {
                    RechargeProcessLog processLog = new RechargeProcessLog();
                    processLog.setRechargeId(unprocessedRecharges.get(0).getId().intValue());
                    processLog.setAdminId(adminId);
                    processLog.setProcessTime(LocalDateTime.now());
                    processLog.setHoursAdded(hours);
                    processLog.setClassId(classId.intValue());
                    // 按比例分配金额
                    BigDecimal classAmount = totalProcessedAmount.multiply(BigDecimal.valueOf(hours))
                            .divide(BigDecimal.valueOf(totalHours), 2, BigDecimal.ROUND_HALF_UP);
                    processLog.setProcessedAmount(classAmount);
                    processLog.setProcessNotes(processNotes + " (多班级分配)");
                    rechargeProcessLogMapper.insert(processLog);
                }
            }
        }
        
        // 7. 写入课时变动日志
        LessonLog log = new LessonLog();
        log.setStudentId(userId);
        log.setChangeValue(totalHours);
        log.setType(LessonLog.ChangeType.RECHARGE);
        log.setTitle("多班级充值");
        log.setDescription(processNotes + " (总课时: " + totalHours + ", 分配详情: " + classHoursMap.toString() + ")");
        log.setTime(new Date());
        log.setAdminId(adminId);
        lessonLogMapper.insert(log);
    }

    @Override
    public Map<Long, BigDecimal> getClassPrices() {
        List<CourseClass> classes = courseClassMapper.selectList(null);
        return classes.stream().collect(
            Collectors.toMap(CourseClass::getId, CourseClass::getPricePerHour)
        );
    }
}
